package org.teamswift.crow.rbac.security.realms;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.util.ByteSource;
import org.teamswift.crow.rbac.entity.CrowUser;
import org.teamswift.crow.rbac.security.PasswordHelper;
import org.teamswift.crow.rbac.security.token.CrowUsernameToken;
import org.teamswift.crow.rbac.service.CrowUserService;
import org.teamswift.crow.rest.exception.CrowErrorMessage;
import org.teamswift.crow.rest.exception.impl.DataNotFoundException;
import org.teamswift.crow.rest.utils.CrowBeanUtils;
import org.teamswift.crow.rest.utils.CrowMessageUtil;

public class CrowUsernameRealm extends AuthenticatingRealm {

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof CrowUsernameToken;
    }

    {
        this.setCredentialsMatcher(PasswordHelper.getHashMatcher());
    }


    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        CrowUsernameToken usernameToken = (CrowUsernameToken) token;

        CrowUserService crowUserService = CrowBeanUtils.getBean(CrowUserService.class);

        CrowUser user = crowUserService.findOneByUsernameOrMobile(usernameToken.getUsername()).orElseThrow(() -> {
            throw new DataNotFoundException(
                    CrowMessageUtil.error(CrowErrorMessage.NotFoundByID)
            );
        });

        return new SimpleAuthenticationInfo(
                user, user.getPassword(),
                ByteSource.Util.bytes(user.getSalt()),
                user.getName()
        );
    }

}
